<?php
/**
 *阿里大鱼
 * User: 梁晓伟  lxw11109@gmail.com
 * Date: 2017-09-04
 * Time: 15:10
 */

namespace App\Libs\Contracts\SMS;

//require_once dirname(__DIR__) . '/api_sdk/vendor/autoload.php';

use App\Libs\Contracts\api_sdk\lib\Core\DefaultAcsClient;
use App\Libs\Contracts\api_sdk\lib\Core\Config;
use App\Libs\Contracts\api_sdk\lib\Api\Sms\Request\V20170525\SendSmsRequest;
use App\Libs\Contracts\api_sdk\lib\Core\Profile\DefaultProfile;
use App\Libs\Contracts\SmsInterface;
use App\Libs\Sms\AliSms;
use Illuminate\Support\Facades\DB;

class AliImpl implements SmsInterface
{

    static $acsClient = null;
    public function __construct()
    {
    }
    public static function getAcsClient() {


        //产品名称:云通信短信服务API产品,开发者无需替换
        $product = "Dysmsapi";

        //产品域名,开发者无需替换
        $domain = "dysmsapi.aliyuncs.com";

        // TODO 此处需要替换成开发者自己的AK (https://ak-console.aliyun.com/)
        $accessKeyId = "LTAI5t7vA3qfDyvwzzRZxwWB"; // AccessKeyId

        $accessKeySecret = "UjHW2kt7gWZxES8PPjS2xXWtMpWk3v"; // AccessKeySecret

        // 暂时不支持多Region
        $region = "cn-hangzhou";

        // 服务结点
        $endPointName = "cn-hangzhou";


        if(static::$acsClient == null) {

            //初始化acsClient,暂不支持region化
            $profile = DefaultProfile::getProfile($region, $accessKeyId, $accessKeySecret);

            // 增加服务结点
            DefaultProfile::addEndpoint($endPointName, $region, $product, $domain);

            // 初始化AcsClient用于发起请求
            static::$acsClient = new DefaultAcsClient($profile);
        }
        return static::$acsClient;
    }
    /**
     * @param \App\Libs\Contracts\手机号 $mobile
     * @param \App\Libs\Contracts\验证码类型 $type
     * @param string $bz
     * @return array
     */
    public function send($mobile, $type, $bz='')
    {
        Config::load();
        // 初始化SendSmsRequest实例用于设置发送短信的参数
        $request = new SendSmsRequest();

        //可选-启用https协议
        //$request->setProtocol("https");

        // 必填，设置短信接收号码
        $request->setPhoneNumbers($mobile);

        // 必填，设置签名名称，应严格按"签名名称"填写，请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
        $request->setSignName("乡米网");

        // 必填，设置模板CODE，应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
        $request->setTemplateCode("SMS_226825378");
        $code = mt_rand(100000, 999999);
        \RedisDB::setex($mobile,300,$code);
        // 可选，设置模板参数, 假如模板中存在变量需要替换则为必填项
        $request->setTemplateParam(json_encode(array(  // 短信模板中字段的值
            "code"=>$code,
        ), JSON_UNESCAPED_UNICODE));

        // 可选，设置流水号
      //  $request->setOutId("yourOutId");

        // 选填，上行短信扩展码（扩展码字段控制在7位或以下，无特殊需求用户请忽略此字段）
       // $request->setSmsUpExtendCode("1234567");

        // 发起访问请求
        $acsResponse = static::getAcsClient()->getAcsResponse($request);
        \Log::info("==============");
        \Log::info($mobile);
        return 100;

    }
    public function sendAudit($mobile, $templateCode, $param)
    {
        Config::load();
        // 初始化SendSmsRequest实例用于设置发送短信的参数
        $request = new SendSmsRequest();

        //可选-启用https协议
        //$request->setProtocol("https");

        // 必填，设置短信接收号码
        $request->setPhoneNumbers($mobile);

        // 必填，设置签名名称，应严格按"签名名称"填写，请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
        $request->setSignName("星途网");

        // 必填，设置模板CODE，应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
        $request->setTemplateCode($templateCode);
//        $code = mt_rand(100000, 999999);
//
//        \RedisDB::setex($mobile,300,$code);
        // 可选，设置模板参数, 假如模板中存在变量需要替换则为必填项
        $request->setTemplateParam(json_encode($param, JSON_UNESCAPED_UNICODE));

        // 可选，设置流水号
        //  $request->setOutId("yourOutId");

        // 选填，上行短信扩展码（扩展码字段控制在7位或以下，无特殊需求用户请忽略此字段）
        // $request->setSmsUpExtendCode("1234567");

        // 发起访问请求
        $acsResponse = static::getAcsClient()->getAcsResponse($request);
        \Log::info("==============");
        \Log::info($mobile);
        return 100;

    }
    /**
     * @param \App\Libs\Contracts\手机号 $mobile
     * @param \App\Libs\Contracts\发送类型 $type
     * @param \App\Libs\Contracts\验证码 $smscode
     * @return array
     */
    public function check($mobile, $type, $smscode)
    {
        return $this->checkReturn($mobile, $type, $smscode);
    }

    /**
     * 验证短信校验码
     * @param $mobile
     * @param $type
     * @param $smscode
     * @return int
     */
    protected function checksms($mobile, $type, $smscode)
    {
        //检测手机校验码是否过期
        $smstime = substr(session('sms_time_'.$type), 0, strpos(session('sms_time_'.$type), '_'));
        $over = time() - $smstime;
        if ($over >= 60*10) {
            return -100;
        }
        $condition = array();
        $condition['code_phone'] = $mobile;
        $condition['code_type']  = $type;
        $condition['send_time'] = $sendtime = substr(session('sms_time_'.$type) , 0 , strpos(session('sms_time_'.$type), '_'));
        $data = DB::table('code_record')->where($condition)->first();

        if (!$data) {
            return -200;
        }
        if ($data->validate_state == '1' && $data->code == $smscode) {
            // 设置效验码已验证
            DB::update('update mall_code_record set validate_state = 2 where code_phone = ? and code_type = ? and send_time = ?', [$mobile, $type, $sendtime]);
            session(['sms_time_'.$type => null]); // 删除SESSION内容
            return  100;
        } else {
            return -300;
        }
    }

    /**
     * 发送短信
     *
     * @param \App\Libs\Contracts\手机号 $mobile
     * @param $type
     * @param \App\Libs\Contracts\内容 $content
     */
    public function sendOnly($mobile, $type, $content)
    {
        $sms = new AliSms();
        list($sms_type, $content) = $this->getTypeContent($type);
        $sms_res = $sms->send($mobile, $sms_type, $content);
    }


    protected function makesms($type, $phone, $code)
    {
        $stime = strtotime(date('Y-m-d', time()));
        $etime = time();

        $sms = new AliSms(); //阿里大于接口
        list($sms_type, $content) = $this->getTypeContent($type, $code);

        $sms_res = $sms->send($phone, $sms_type, $content);

        if (!$sms_res) {
            return -100;
        }
        return 100;

    }


    private function getTypeContent($type, $code)
    {
        $code_rep =  "code";
        $code_smtype = $type;
        $param = explode(',', $code_rep);
        $param = $this->repParameter($param, $code);
        return [$code_smtype, $param];


        $message = ncReplaceText($tpl_info->content, $param);
        return $message;
    }


    protected function checkReturn($mobile, $type, $smscode)
    {
        $result = $this->checksms($mobile, $type, $smscode);
        $success = false;
        switch($result)
        {
            case '-200':
                $msg = '验证码错误';
                $resultcode = '-200';
                break;
            case '-300':
                $msg = '验证码已使用';
                $resultcode = '-300';
                break;
            case '-100':
                $msg = '验证码已过期';
                $resultcode = '-100';
                break;
            case '100':
                $msg = '验证码正确';
                $resultcode = '100';
                $success = true;
                break;
        }
        return [$success, $msg, $resultcode];
    }


    protected function sendsms($phone, $type, $bz='')
    {
        $code = mt_rand(100000, 999999);
        $result = $this->makesms($type, $phone, $code);
        \RedisDB::setex($phone,1800,$code);
         return $result;

    }


    private function repParameter($param = array(), $code = '')
    {
        static $array;
        $smstype = ['time' => time()];
        foreach ($smstype  as $key => $value) {
            if (in_array($key, $param)) {
                $array[$key] = (string)$value;
            }
        }
        $array['code'] = (string)$code;
        return json_encode($array);
    }
}